/// 
/// Copyright (c) 2018 Zeutro, LLC. All rights reserved.
/// 
/// This file is part of Zeutro's OpenABE.
/// 
/// OpenABE is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published by
/// the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
/// 
/// OpenABE is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/// GNU Affero General Public License for more details.
/// 
/// You should have received a copy of the GNU Affero General Public
/// License along with OpenABE. If not, see <http://www.gnu.org/licenses/>.
/// 
/// You can be released from the requirements of the GNU Affero General
/// Public License and obtain additional features by purchasing a
/// commercial license. Buying such a license is mandatory if you
/// engage in commercial activities involving OpenABE that do not
/// comply with the open source requirements of the GNU Affero General
/// Public License. For more information on commerical licenses,
/// visit <http://www.zeutro.com>.
///
/// \file   zscanner.h
///
/// \brief  Class definition for zpolicy scanner.
///
/// \author J. Ayo Akinyele
///

#ifndef __ZSCANNER_H__
#define __ZSCANNER_H__

// Flex expects the signature of yylex to be defined in the macro YY_DECL, and
// the C++ parser expects it to be declared. We can factor both as follows.

#ifndef YY_DECL

#define	YY_DECL						\
  oabe::Parser::token_type	\
  oabe::Scanner::lex(			\
  oabe::Parser::semantic_type* yylval,	\
  oabe::Parser::location_type* yylloc	\
  )
#endif

#ifndef __FLEX_LEXER_H
#define yyFlexLexer OpenABEFlexLexer
#include <FlexLexer.h>
#undef yyFlexLexer
#endif

#include <openabe/zparser.tab.hh>

#define EXPINT_KEYWORD  "expint"

namespace oabe {

/** Scanner is a derived class to add some extra function to the scanner
 * class. Flex itself creates a class named yyFlexLexer, which is renamed using
 * macros to ZtkFlexLexer. However we change the context of the generated
 * yylex() function to be contained within the Scanner class. This is required
 * because the yylex() defined in ZtkFlexLexer has no parameters. */
class Scanner : public OpenABEFlexLexer
{
public:
  /** Create a new scanner object. The streams arg_yyin and arg_yyout default
   * to cin and cout, but that assignment is only made when initializing in
   * yylex(). */
  Scanner(std::istream* arg_yyin = 0,
    std::ostream* arg_yyout = 0);

  /** Required for virtual functions */
  virtual ~Scanner();

  /** This is the main lexing function. It is generated by flex according to
   * the macro declaration YY_DECL above. The generated bison parser then
   * calls this virtual function to fetch new tokens. */
  virtual Parser::token_type lex(Parser::semantic_type* yylval,
                                 Parser::location_type* yylloc);

  /** Enable debug output (via arg_yyout) if compiled into the scanner. */
  void set_debug(bool b);
};

} // namespace oabe

#endif // OpenABE_SCANNER_H
